A total of 6127 characters, expected to take 16 minutes to complete reading.
Download Address
Open Source Address:https://github.com/mcdudu233/FileSystem.git
Download address:https://github.com/mcdudu233/FileSystem/releases/tag/exe
Code Design
1. First design the structure of FCB and the structure of directory items
class file {
private:
/* 基本信息 */
string name; // * 关键字:文件名
string father; // 所属的目录名
vector<int> point;// 所有数据块的指针
/* 存取控制 */
int master; // 所属用户
char masterPrivilege;// 主用户权限
char otherPrivilege; // 其他用户权限
/* 使用信息 */
int size; // 大小
chrono::system_clock::time_point createTime;// 创建时间
chrono::system_clock::time_point modifyTime;// 修改时间
According to the characteristics of the cpp class, we simplify the FCB into a file class, which contains the basic information of the FCB, access control information and usage information, with the file name as the key. At the same time, we adopt a single-level index organization, so we set the pointer array of all data blocks.
The same is true for directories. We divide directory items into subdirectories and files to save them separately. The key word is the directory name:
class directory {
private:
/* 基本信息 */
string name; // * 关键字:目录名
string father; // 父目录的目录名
vector<directory> directories;// 目录下的子目录
vector<file> files; // 目录下的文件
/* 存取控制 */
int master = user_root.getUid();// 所属用户
char masterPrivilege; // 所有者权限
char otherPrivilege; // 其他人权限
/* 使用信息 */
chrono::system_clock::time_point createTime;// 创建时间
chrono::system_clock::time_point modifyTime;// 修改时间
For users, we also set up a class to manage:
class user {
private:
int uid; // * 关键字:用户 uid
string name; // 用户名
string password;// 用户密码 采用 MD5 加密
bool superuser; // 是否是超级用户
2. Improve the methods and properties of each class.
file (file) class:
public:
file();
file(const string &fileName, string father, int master);
file(const file &file);
~file();
bool operator==(const file &other);
public:
string getName(); // 获取用户名
bool setName(string name);// 设置用户名
int getSize(); // 获取文件大小
/* 文件操作 */
bool clearFile(); // 清空所有文件内容
char *readFile(); // 读取的文件内容
bool writeFile(char *data, int size);// 写入文件内容
/* 存取控制 */
int getUser(); // 获取用户
bool setUser(int uid); // 设置用户
bool setMasterPrivilege(char masterPrivilege); // 设置文件所有者权限
bool setOtherPrivilege(char otherPrivilege); // 设置其他用户的权限
bool hasMasterPrivilege_read(char masterPrivilege); // 判断所有者是否有读取权限
bool hasMasterPrivilege_write(char masterPrivilege); // 判断所有者是否有写入权限
bool hasMasterPrivilege_execute(char masterPrivilege);// 判断所有者是否有执行权限
bool hasOtherPrivilege_read(char otherPrivilege); // 判断其他用户是否有读取权限
bool hasOtherPrivilege_write(char otherPrivilege); // 判断其他用户是否有写入权限
bool hasOtherPrivilege_execute(char otherPrivilege); // 判断其他用户是否有执行权限
/* 使用信息 */
chrono::system_clock::time_point getCreateTime();// 获取创建时间
chrono::system_clock::time_point getModifyTime();// 获取修改时间
/* 序列化 */
void serialize(fstream &out) const;// 序列化
void deserialize(fstream &in); // 反序列化
directory (folder) class:
public:
directory();
directory(string name, string father, int master);
directory(const directory &dir);
~directory();
bool operator==(const directory &other);
public:
string getName(); // 获取目录名
bool setName(string name); // 设置用户名
string getFather(); // 获取父目录名
bool setFather(string father);// 设置父目录名
/* 目录操作 */
vector<directory> *getDirectories(); // 获取所有子目录
vector<file> *getFiles(); // 获取所有文件
bool addFile(file file); // 新增文件
bool addDirectory(directory dir); // 新增目录
bool removeFile(string name); // 删除文件
bool removeDirectory(string name); // 删除目录
file *getFile(string name); // 根据名字获取文件 没有返回 nullptr
directory *getDirectory(string name);// 根据名字获取目录 没有返回 nullptr
bool has(string name); // 目录中有这个文件 (目录或者文件)
bool hasFile(string name); // 目录中有这个文件
bool hasDirectory(string name); // 目录中有这个目录
/* 存取控制 */
int getUser(); // 获取所属用户
bool setUser(int uid); // 设置所属用户
char getMasterPrivilege(); // 获取所有者权限
char getOtherPrivilege(); // 获取其他用户权限
bool hasMasterPrivilege_read(char masterPrivilege); // 判断所有者是否有读取权限
bool hasMasterPrivilege_write(char masterPrivilege); // 判断所有者是否有写入权限
bool hasMasterPrivilege_execute(char masterPrivilege);// 判断所有者是否有执行权限
bool hasOtherPrivilege_read(char otherPrivilege); // 判断其他用户是否有读取权限
bool hasOtherPrivilege_write(char otherPrivilege); // 判断其他用户是否有写入权限
bool hasOtherPrivilege_execute(char masterPrivilege); // 判断其他用户是否有执行权限
/* 使用信息 */
chrono::system_clock::time_point getCreateTime();// 获取创建时间
chrono::system_clock::time_point getModifyTime();// 获取修改时间
/* 序列化 */
void serialize(fstream &out) const;// 序列化
void deserialize(fstream &in); // 反序列化
};
// 根目录
extern directory dir_root;
user class:
public:
user();
user(int uid, string name, string password = "", bool superuser = false);
~user();
bool operator==(const user &other);
public:
int getUid(); // 获取 UID
string getName(); // 获取用户名
bool setName(string name); // 设置用户名
string getPassword(); // 获取用户密码 MD5
bool setPassword(string password); // 设置用户密码
bool checkPassword(string password);// 检测密码是否一致
bool getSuper(); // 判断是否为超级用户
bool setSuper(bool super); // 设置是否为超级用户
/* 序列化 */
void serialize(fstream &out) const;// 序列化
void deserialize(fstream &in); // 反序列化
};
// 默认用户
extern user user_root;
3. Methods of data processing
We use a single file to save data, that is, a file with the suffix ". hwh.xb.fs" to save our self-made file system:
namespace fs = std::filesystem;
// 文件系统数据的存放路径
#define DATA_PATH "./"
#define DATA_SUFFIX ".hwh.xb.fs"
bool initData(const string &name);
bool closeData();
bool existData(const string &name);
bool setAvailable(vector<bool> *v, int start);
int getSpaceSize();
bool setSpaceSize(int size);
int getBlockSize();
bool setBlockSize(int size);
bool setPosition(int block);// 设置读写指针位置
fstream &getData(); // 获取 file
/* 文件数据读写方法 */
bool hasBlock(int block); // 判断块是否已经有数据了
int availableBlock(); // 获取空闲块
bool useBlock(int block); // 使用空闲块
bool releaseBlock(int block); // 释放已经使用的块
char *readBlock(int block); // 读取某一块
bool writeBlock(int block, char *data, int size);// 写入某一块
#endif//FILESYSTEM_DATA_H
Then test the method of reading and writing, initialize the file content to hexadecimal all 0, here we use winhex software to test and view:
The test is correct, and the data is initialized to all zeros.
4. Complete the file system (filesystem) class
This class is used to call and implement file system operations, using all the previous classes.
First include a file system should have private properties:
private:
vector<string> current;// 当前所在的路径
string name; // 文件系统数据的文件名
int space_size; // 空间大小
int block_size; // 块大小
int block_data; // 开始存数据部分的块地址
user *user_current;// 当前操作系统的用户
vector<user> users;// 所有用户
directory tree; // 根目录
vector<bool> available;// 空闲盘块 位视图法
Here we use the bit diagram method to save the data of the free disk block, because this method is simple and effective, and the modification efficiency is high.
We then complete all the operations that might be used by the file system:
public:
/* 基本 */
string getCurrentPath(); // 获取当前所在的路径
directory *getTree(); // 获取树形目录
directory *getFatherByName(directory dir);// 根据目录找到父目录
directory *getFatherByName(file f); // 根据文件找到父目录
directory *findParentDirectory(directory *current, directory &target);
directory *findParentDirectory(directory *current, file &target);
/* 命令 */
bool ls(vector<List> &v); // 列出当前文件夹下的文件
bool ls(string path, vector<List> &v); // 列出某个文件夹下的文件
int disk(bool left); // 获取磁盘容量 (left 为 true 时返回剩余容量)
bool cd(string path); // 跳转到某个文件夹
bool mkdir(directory d, const string &dname); // 新建文件夹
bool touch(directory d, const string &fname); // 新建文件
bool rm(file f); // 删除文件
bool rm(directory d); // 删除目录
vector<user> usrs(); // 获取所有用户
int useradd(string name, string password = "", bool super = false); // 新增用户
bool userdel(int uid); // 删除用户
bool usercrg(int uid, string name, string password = "", bool super = false);// 修改用户信息
user userbyid(int uid); // 根据 uid 查找用户
The next step is to test our file system class. We try to initialize the class and write some file and folder information:
It is obvious that the file structure is written to the header of the file (our file system allocates a certain header space by default to write file structure information)
Interface Design
Interface
(1) Format window design
(2) Login interface design
(3) Main interface design
(4) Right-click menu
(5) Text editing interface
(6) Top Function Menu
Interface Code
Please check the source code for the interface code, which does not take up valuable space to repeat.
Results
A total of 3689 lines of code were analyzed.